package com.system.comm.utils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.system.handle.model.ResponseFrame;

/**
 * http工具类
 * @author yuejing
 *
 */
public class FrameHttpUtil {

	private static final Logger LOGGER = LoggerFactory.getLogger(FrameHttpUtil.class);
	private static final int HTTP_CONNECT_TIMEOUT = 5000;
	private static final int HTTP_CONNECTION_REQUEST_TIMEOUT = 60000;
	private static final int HTTP_SOCKET_TIMEOUT = 60000;

	private static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException {
		SSLContext sc = SSLContext.getInstance("SSLv3");
		// 实现一个X509TrustManager接口，用于绕过验证，不用修改里面的方法
		X509TrustManager trustManager = new X509TrustManager() {
			@Override
			public void checkClientTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
					String paramString) throws CertificateException {
			}
			@Override
			public void checkServerTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
					String paramString) throws CertificateException {
			}
			@Override
			public java.security.cert.X509Certificate[] getAcceptedIssuers() {
				return null;
			}
		};
		sc.init(null, new TrustManager[] { trustManager }, null);
		return sc;
	}

	/**
	 * 创建支持http和https的请求
	 * @return
	 */
	public static CloseableHttpClient createSSLClientDefault() {
		try {
			// 采用绕过验证的方式处理https请求
			SSLContext sslcontext = createIgnoreVerifySSL();
			// 设置协议http和https对应的处理socket链接工厂的对象
			/*Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create()
					.register("http", PlainConnectionSocketFactory.INSTANCE)
					.register("https", new SSLConnectionSocketFactory(sslcontext,
							SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER))
					.build();*/
			
			/*SSLContext ctx = SSLContext.getInstance(SSLConnectionSocketFactory.TLS);
	        ctx.init(null, new TrustManager[] { trustManager }, null);*/
			SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslcontext, NoopHostnameVerifier.INSTANCE);
			Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
	                .register("http", PlainConnectionSocketFactory.INSTANCE)
	                .register("https",socketFactory)
	                .build();
			
			PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(
					socketFactoryRegistry);
			HttpClients.custom().setConnectionManager(connManager);

			// 创建自定义的httpclient对象
			return HttpClients.custom().setConnectionManager(connManager).build();

			/*SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
				public boolean isTrusted(X509Certificate[] chain,
						String authType) throws CertificateException {
					return true;
				}
			}).build();*/
			/*SSLContext sslContext = SSLContexts.createSystemDefault();

			SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
			return HttpClients.custom().setSSLSocketFactory(sslsf).build();*/
		} catch (Exception e) {
			e.printStackTrace();
		}
		return  HttpClients.createDefault();
	}

	/**
	 * post方式请求
	 * @param url			请求地址
	 * @return
	 * @throws IOException 
	 */
	public static String get(String url) throws IOException {
		String result = null;
		// 创建默认的httpClient实例
		CloseableHttpClient httpClient = createSSLClientDefault();
		// 创建httppost
		HttpGet httpGet = new HttpGet(url);
		RequestConfig requestConfig = RequestConfig.custom()
				.setConnectTimeout(HTTP_CONNECT_TIMEOUT).setConnectionRequestTimeout(HTTP_CONNECTION_REQUEST_TIMEOUT)
				.setSocketTimeout(HTTP_SOCKET_TIMEOUT).build();
		httpGet.setConfig(requestConfig);
		// 创建参数队列
		//try {
		CloseableHttpResponse response = httpClient.execute(httpGet);
		try {
			HttpEntity entity = response.getEntity();
			if (entity != null) {
				result = EntityUtils.toString(entity, "UTF-8");
			}
		} finally {
			response.close();
			httpClient.close();
		}
		return result;
	}

	/**
	 * post方式请求
	 * @param url			请求地址
	 * @param jsonBody	参数内容格式为: {"name":"你好"}
	 * @return
	 * @throws IOException 
	 */
	public static String post(String url, String jsonBody) throws IOException {
		String result = null;
		// 创建默认的httpClient实例
		CloseableHttpClient httpClient = createSSLClientDefault();
		// 创建httppost
		HttpPost httpPost = new HttpPost(url);
		RequestConfig requestConfig = RequestConfig.custom()
				.setConnectTimeout(HTTP_CONNECT_TIMEOUT).setConnectionRequestTimeout(HTTP_CONNECTION_REQUEST_TIMEOUT)
				.setSocketTimeout(HTTP_SOCKET_TIMEOUT).build();
		httpPost.setConfig(requestConfig);
		// 创建参数队列
		//try {
		StringEntity input = new StringEntity(jsonBody, "UTF-8");
		input.setContentType("application/json;charset=utf-8");
		httpPost.setEntity(input);
		CloseableHttpResponse response = httpClient.execute(httpPost);
		try {
			HttpEntity entity = response.getEntity();
			if (entity != null) {
				result = EntityUtils.toString(entity, "UTF-8");
			}
		} finally {
			response.close();
			httpClient.close();
		}
		/*} catch (ClientProtocolException e) {
			LOGGER.error("异常" + e.getMessage(), e);
		} catch (UnsupportedEncodingException e) {
			LOGGER.error("异常" + e.getMessage(), e);
		} catch (IOException e) {
			LOGGER.error("异常" + e.getMessage(), e);
		} finally {
			try {
				httpclient.close();
			} catch (IOException e) {
				LOGGER.error("异常" + e.getMessage(), e);
			}
		}*/
		return result;
	}

	/**
	 * post方式请求
	 * @param url			请求地址
	 * @param params		系统参数
	 * @return
	 * @throws IOException 
	 */
	public static String post(String url, Map<String, Object> params) throws IOException {
		String result = null;
		// 创建默认的httpClient实例.
		CloseableHttpClient httpClient = createSSLClientDefault();
		// 创建httppost
		HttpPost httpPost = new HttpPost(url);
		RequestConfig requestConfig = RequestConfig.custom()
				.setConnectTimeout(HTTP_CONNECT_TIMEOUT).setConnectionRequestTimeout(HTTP_CONNECTION_REQUEST_TIMEOUT)
				.setSocketTimeout(HTTP_SOCKET_TIMEOUT).build();
		httpPost.setConfig(requestConfig);
		// 创建参数队列 
		List<NameValuePair> formparams = new ArrayList<NameValuePair>();
		Iterator<Entry<String, Object>> entryKeyIterator = params.entrySet().iterator();
		while (entryKeyIterator.hasNext()) {
			Entry<String, Object> e = entryKeyIterator.next();
			String value = null;
			if(e.getValue() != null) {
				value = e.getValue().toString();
			}
			formparams.add(new BasicNameValuePair(e.getKey(), value));
		}
		UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8");
		httpPost.setEntity(uefEntity);
		CloseableHttpResponse response = httpClient.execute(httpPost);
		try {
			HttpEntity entity = response.getEntity();
			if (entity != null) {
				result = EntityUtils.toString(entity, "UTF-8");
			}
		} finally {
			response.close();
			httpClient.close();
		}
		return result;
	}

	/**
	 * delete方式请求
	 * @param url			请求地址
	 * @return
	 * @throws IOException 
	 */
	public static String delete(String url) throws IOException {
		String result = null;
		// 创建默认的httpClient实例.
		CloseableHttpClient httpClient = createSSLClientDefault();
		// 创建httppost
		HttpDelete httpDelete = new HttpDelete(url);
		RequestConfig requestConfig = RequestConfig.custom()
				.setConnectTimeout(HTTP_CONNECT_TIMEOUT).setConnectionRequestTimeout(HTTP_CONNECTION_REQUEST_TIMEOUT)
				.setSocketTimeout(HTTP_SOCKET_TIMEOUT).build();
		httpDelete.setConfig(requestConfig);
		// 创建参数队列 
		/*List<NameValuePair> formparams = new ArrayList<NameValuePair>();
		Iterator<Entry<String, Object>> entryKeyIterator = params.entrySet().iterator();
		while (entryKeyIterator.hasNext()) {
			Entry<String, Object> e = entryKeyIterator.next();
			String value = null;
			if(e.getValue() != null) {
				value = e.getValue().toString();
			}
			formparams.add(new BasicNameValuePair(e.getKey(), value));
		}
		UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8");
		httpDelete.setEntity(uefEntity);*/
		CloseableHttpResponse response = httpClient.execute(httpDelete);
		try {
			HttpEntity entity = response.getEntity();
			if (entity != null) {
				result = EntityUtils.toString(entity, "UTF-8");
			}
		} finally {
			response.close();
			httpClient.close();
		}
		return result;
	}
	
	/**
	 * 下载文件到指定的本地路径
	 * @param url
	 * @param savePath
	 * @return
	 */
	public static String download(String url, String savePath) {
		ResponseFrame frame = new ResponseFrame();
		InputStream inputStream = null;
		FileOutputStream fos = null;
		try {
			URL u = new URL(url);
			HttpURLConnection conn = (HttpURLConnection) u.openConnection();
			//设置超时间为3秒
			conn.setConnectTimeout(HTTP_CONNECT_TIMEOUT);
			//防止屏蔽程序抓取而返回403错误
			conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");

			//得到输入流
			inputStream = conn.getInputStream();
			//获取自己数组
			byte[] getData = readInputStream(inputStream);
			File file = new File(savePath);
			//文件保存位置
			FrameFileUtil.createDir(file);
			fos = new FileOutputStream(file);
			fos.write(getData);
		} catch (IOException e) {
			LOGGER.error(e.getMessage(), e);
			frame.setCode(-2);
			frame.setMessage(e.getMessage());
		} finally {
			try {
				if(fos != null) {
					fos.close();
				}
				if(inputStream != null){
					inputStream.close();
				}
			} catch (IOException e) {
			}
		}
		return savePath;
	}
	/**
	 * 从输入流中获取字节数组
	 * @param inputStream
	 * @return
	 * @throws IOException
	 */
	private static byte[] readInputStream(InputStream inputStream) throws IOException {
		byte[] buffer = new byte[1024];
		int len = 0;
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		while((len = inputStream.read(buffer)) != -1) {
			bos.write(buffer, 0, len);
		}
		bos.close();
		return bos.toByteArray();
	}

	public static void main(String[] args) throws IOException {
		Map<String, Object> params = new HashMap<String, Object>(10);
		String str = post("http://invest.52jingya.com/index.jsp", params);
		System.out.println("str: " + str);
	}
}